package com.jdwx.opengl.kotlin

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.*
import kotlin.system.measureTimeMillis

//
//val threadLocal = ThreadLocal<String?>() // 声明线程局部变量
//
//fun main() = runBlocking<Unit> {
//    threadLocal.set("main")
//    println("Pre-main, current thread: ${Thread.currentThread()}, thread local value: '${threadLocal.get()}'")
//    val job = launch(Dispatchers.Default + threadLocal.asContextElement(value = "launch")) {
//        println("Launch start, current thread: ${Thread.currentThread()}, thread local value: '${threadLocal.get()}'")
//        yield()
//        println("After yield, current thread: ${Thread.currentThread()}, thread local value: '${threadLocal.get()}'")
//    }
//    job.join()
//    println("Post-main, current thread: ${Thread.currentThread()}, thread local value: '${threadLocal.get()}'")
//}


//fun main() {
//    fun foo(): List<Int> = listOf(1, 2, 3)
//
//    foo().forEach { value -> println(value) }
//
//
//}



//
//fun main() = runBlocking<Unit> {
//    suspend fun foo(): List<Int> {
//        delay(1000) // 假装我们在这里做了一些异步的事情
//        println("1111111111")
//        return listOf(1, 2, 3)
//    }
//    println("xiaobai1")
//    foo().forEach { value -> println(value) }
//    println("xiaobai2")
//}

//流



//@InternalCoroutinesApi
//fun main() = runBlocking<Unit> {
//
//    fun foo(): Flow<Int> = flow { // 流构建器
//        for (i in 1..3) {
//            delay(100) // 假装我们在这里做了一些有用的事情
//            emit(i) // 发送下一个值
//        }
//    }
//
//    // 启动并发的协程以验证主线程并未阻塞
//    launch {
//        for (k in 1..3) {
//            println("I'm not blocked $k")
//            delay(100)
//        }
//    }
//    // 收集这个流
//    foo().collect { value -> println(value) }
//}


//
//fun main() = runBlocking<Unit> {
//
//    fun foo(): Flow<Int> = flow {
//        println("Flow started")
//        for (i in 1..3) {
//            delay(100)
//            emit(i)
//        }
//    }
//
//    println("Calling foo...")
//    val flow = foo()
//    println("Calling collect...")
//    flow.collect { value -> println(value) }
//    delay(3000 )
//    println("Calling collect again...")
//    flow.collect { value -> println(value) }
//}



//fun main() = runBlocking<Unit> {
//
//    fun foo(): Flow<Int> = flow {
//        for (i in 1..3) {
//            delay(100)
//            println("Emitting $i")
//            emit(i)
//        }
//    }
//
//    withTimeoutOrNull(250) { // 在 250 毫秒后超时
//        foo().collect { value -> println(value) }
//    }
//    println("Done")
//
//    (1..100).asFlow().collect { value11 -> println(value11) }
//
//
//}

//
//suspend fun performRequest(request: Int): String {
//    delay(1000) // 模仿长时间运行的异步工作
//    return "response $request"
//}
//
//fun main() = runBlocking<Unit> {
//    (1..3).asFlow() // 一个请求流
//            .map { request -> performRequest(request) }
//            .collect { response -> println(response) }
//
//
//    (1..3).asFlow() // 一个请求流
//            .transform { request ->
//                emit("Making request $request")
//                emit(performRequest(request))
//            }
//            .collect { response -> println(response) }
//}


////限长操作符
//fun numbers(): Flow<Int> = flow {
//    try {
//        emit(1)
//        emit(2)
//        println("This line will not execute")
//        emit(3)
//        delay(1000)
//    } finally {
//        println("Finally in numbers")
//    }
//}
//
//fun main() = runBlocking<Unit> {
//    numbers()
//            .take(2) // 只获取前两个
//            .collect { value -> println(value) }
//}

//fun main() = runBlocking<Unit> {
//
//
//    fun foo(): Flow<Int> = flow {
//        for (i in 1..3) {
//            delay(1000) // 假装我们异步等待了 100 毫秒
//            emit(i) // 发射下一个值
//        }
//    }
//
//
//    val time = measureTimeMillis {
//        foo()
//                .buffer() // 缓冲发射项，无需等待
//                .collect { value ->
//                    delay(300) // 假装我们花费 300 毫秒来处理它
//                    println(value)
//                }
//    }
//    println("Collected in $time ms")
//
//}
//




//fun main() = runBlocking<Unit> {
//    fun foo(): Flow<Int> = flow {
//        for (i in 1..4) {
//            delay(100) // 假装我们异步等待了 100 毫秒
//            emit(i) // 发射下一个值
//        }
//    }
//    val time = measureTimeMillis {
//        foo()
//                .conflate() // 合并发射项，不对每个值进行处理
//                .collect { value ->
//                    delay(1000) // 假装我们花费 300 毫秒来处理它
//                    println(value)
//                }
//    }
//    println("Collected in $time ms")
//}
//




//fun main() = runBlocking<Unit> {
//
//    fun foo(): Flow<Int> = flow {
//        for (i in 1..3) {
//            delay(100) // 假装我们异步等待了 100 毫秒
//            emit(i) // 发射下一个值
//        }
//    }
//
//    val time = measureTimeMillis {
//        foo()
//                .collectLatest { value -> // 取消并重新发射最后一个值
//                    println("Collecting $value")
//                    delay(300) // 假装我们花费 300 毫秒来处理它
//                    println("Done $value")
//                }
//    }
//    println("Collected in $time ms")
//}


//fun main() = runBlocking{
//    val nums = (1..3).asFlow().onEach { delay(300) } // 发射数字 1..3，间隔 300 毫秒
//    val strs = flowOf("one", "two", "three").onEach { delay(400) } // 每 400 毫秒发射一次字符串
//    val startTime = System.currentTimeMillis() // 记录开始的时间
//    nums.zip(strs) { a, b -> "$a -> $b" } // 使用“zip”组合单个字符串
//            .collect { value -> // 收集并打印
//                println("$value at ${System.currentTimeMillis() - startTime} ms from start")
//            }
//}



fun main() = runBlocking {
//    val channel = Channel<Int>()
//    launch {
//        // 这里可能是消耗大量 CPU 运算的异步逻辑，我们将仅仅做 5 次整数的平方并发送
//        for (x in 1..5) channel.send(x * x)
//    }
//    // 这里我们打印了 5 次被接收的整数：
//    repeat(5) { println(channel.receive()) }
//    println("Done!")


    val channel = Channel<Int>()
    launch {
        for (x in 1..5) channel.send(x * x)
        channel.close() // 我们结束发送
    }
// 这里我们使用 `for` 循环来打印所有被接收到的元素（直到通道被关闭）
    //delay(5000)
    for (y in channel) println(y)
    println("Done!")


}